#include <view3dinteractorstyle.h>

vtkStandardNewMacro(View3DInteractorStyle);

View3DInteractorStyle::View3DInteractorStyle() :
  vtkInteractorStyleTrackballCamera()
{
	propPicker = vtkPropPicker::New();
	timer = NULL;
	lastPos = NULL;
}

View3DInteractorStyle::~View3DInteractorStyle()
{
	
}

void View3DInteractorStyle::setRenderer(vtkRenderer* render)
{
	renderer = render;
}

void View3DInteractorStyle::Rotate()
{
	vtkInteractorStyleTrackballCamera::Rotate();
	emit viewPointChanged(renderer);
}

void View3DInteractorStyle::Spin()
{
	vtkInteractorStyleTrackballCamera::Spin();
	emit viewPointChanged(renderer);
}

void View3DInteractorStyle::Pan()
{
	vtkInteractorStyleTrackballCamera::Pan();
	emit viewPointChanged(renderer);
}

void View3DInteractorStyle::Dolly()
{
	vtkInteractorStyleTrackballCamera::Dolly();
	emit viewPointChanged(renderer);
}

void View3DInteractorStyle::OnMouseMove()
{
	vtkInteractorStyleTrackballCamera::OnMouseMove();

	if(timer)
		timer->stop();

	isMouseMoving = true;
	this->renderer->GetRenderWindow()->Render();

	//#ifndef _DEBUG //only in release mode, too slow for debug
	if(!timer)
	{
		timer = new QTimer();
		connect(timer,SIGNAL(timeout()), this, SLOT(on_requestInfo()));
	}
	timer->start(500);
	//#endif
}

void View3DInteractorStyle::on_requestInfo()
{
	int xy[2];

	renderer->GetRenderWindow()->Render();
	
	this->GetInteractor()->GetLastEventPosition(xy);
	if(propPicker->PickProp(xy[0],xy[1],renderer)) //if something was 'picked'
	{
		vtkActor* actorPicked = (vtkActor*)propPicker->GetProp3D();
		double range[2];
		actorPicked->GetMapper()->GetScalarRange(range);
		if(range[0] >= 2000)
			emit objectInfoRequested(QPoint(xy[0],xy[1]),range[0],range[1]);
	}
}

void View3DInteractorStyle::OnLeftButtonDown()
{
	vtkInteractorStyleTrackballCamera::OnLeftButtonDown();
	isMouseMoving = false;
}

void View3DInteractorStyle::OnLeftButtonUp()
{
	bool shift = this->GetInteractor()->GetShiftKey();
	bool ctrl = this->GetInteractor()->GetControlKey();

	vtkInteractorStyleTrackballCamera::OnLeftButtonUp();
	if(!isMouseMoving)
	{
		int xy[2];
		this->GetInteractor()->GetLastEventPosition(xy);
		if(propPicker->PickProp(xy[0],xy[1],renderer)) //if something was 'picked'
		{
			vtkActor* actorPicked = (vtkActor*)propPicker->GetProp3D();
			//HighlightProp(actorPicked);
			double range[2];
			actorPicked->GetMapper()->GetScalarRange(range);
			if(range[0] == range[1]) //picked object is a region
			{
				selectedRegions.clear();
				selectedRegions.push_back(range[0]);
				if(shift)
					emit selectedRegionsChanged(selectedRegions,AbstractView::AddToSelection);
				else if(ctrl)
					emit selectedRegionsChanged(selectedRegions,AbstractView::RemoveFromSelection);
				else
					emit selectedRegionsChanged(selectedRegions,AbstractView::NewSelection);
			}
			else //picked object is a link
			{
				selectedLinks.clear();
				selectedLinks.push_back(QPoint(range[0],range[1]));
				if(shift)
					emit selectedLinksChanged(selectedLinks,AbstractView::AddToSelection);
				else if(ctrl)
					emit selectedLinksChanged(selectedLinks,AbstractView::RemoveFromSelection);
				else
					emit selectedLinksChanged(selectedLinks,AbstractView::NewSelection);
			}
		}
	}
}

void View3DInteractorStyle::OnMiddleButtonDown()
{
	vtkInteractorStyleTrackballCamera::OnMiddleButtonDown();
}

void View3DInteractorStyle::OnMiddleButtonUp()
{
	vtkInteractorStyleTrackballCamera::OnMiddleButtonUp();
}

void View3DInteractorStyle::OnRightButtonDown()
{
	vtkInteractorStyleTrackballCamera::OnRightButtonDown();
	isMouseMoving = false;
}

void View3DInteractorStyle::OnRightButtonUp()
{
	vtkInteractorStyleTrackballCamera::OnRightButtonUp();
	if(!isMouseMoving)
	{
		int xy[2];
		this->GetInteractor()->GetLastEventPosition(xy);
		if(propPicker->PickProp(xy[0],xy[1],renderer)) //if something was 'picked'
		{
			vtkActor* actorPicked = (vtkActor*)propPicker->GetProp3D();
			double range[2];
			actorPicked->GetMapper()->GetScalarRange(range);
			emit objectInfoRequested(QPoint(xy[0],xy[1]),range[0],range[1]);
		}
	}
}

void View3DInteractorStyle::on_viewPointChanged(vtkRenderer *otherRenderer)
{
	//viewport in other window changed, adjust to that!
	vtkCamera *myCam = renderer->GetActiveCamera();
	vtkCamera *otherCam = otherRenderer->GetActiveCamera();
	myCam->SetPosition(otherCam->GetPosition());
	myCam->SetFocalPoint(otherCam->GetFocalPoint());
	myCam->SetViewUp(otherCam->GetViewUp());
	myCam->SetViewAngle(otherCam->GetViewAngle());
	myCam->SetClippingRange(otherCam->GetClippingRange());
	renderer->GetRenderWindow()->Render();
}